module spi_ahb_wrap(
           clk,
           reset_n,

           // AHB Slave
           sHADDR,
           sHWDATA,
           sHWRITE,
           sHREADYOUT,
           sHSIZE,
           sHBURST,
           sHSEL,
           sHTRANS,
           sHRDATA,
           sHRESP,
           sHREADY,
           sHPROT,

           // sdio
           spi_sclk,
           spi_mosi,
           spi_miso,
           spi_ss
       );


localparam [1:0]AHB_TRANS_IDLE = 2'b00,
           AHB_TRANS_BUSY = 2'b01,
           AHB_TRANS_NONSEQ = 2'b10,
           AHB_TRANS_SEQ = 2'b11;

input clk;
input reset_n;

//////////// AHB Slave to Wishbone
input [7:0]     sHADDR;
input [31:0]    sHWDATA;
input           sHWRITE;
input [2:0]     sHSIZE;
input [2:0]     sHBURST;
input           sHSEL;
input [1:0]     sHTRANS;
input           sHREADY;
input [3:0]     sHPROT;

output          sHREADYOUT;
output [31:0]   sHRDATA;
output [1:0]    sHRESP;

output spi_sclk;
output spi_mosi;
input spi_miso;
output spi_ss;

wire [31:0]     wb_dat_i;
wire [7:0]      wb_adr_i;
wire [3:0]      wb_sel_i;
wire            wb_we_i;
wire            wb_cyc_i;
wire            wb_stb_i;
wire [31:0]     wb_dat_o;
wire            wb_ack_o;

reg         next_wb_cyc_i;
reg         next_wb_stb_i;
// 1: 4'b1111, 0: 4'b0000
reg         next_wb_sel_i;

// AHB address & control signal
reg [7:0]   next_wb_adr_i;
reg [7:0]   ito_wb_adr_i;

reg         next_wb_we_i;
reg         ito_wb_we_i;

reg         next_HRESP;
reg         is_HRESP;

assign wb_adr_i = next_wb_adr_i;
assign wb_we_i = next_wb_we_i;
assign wb_dat_i = sHWDATA;
assign wb_cyc_i = next_wb_cyc_i;
assign wb_stb_i = next_wb_stb_i;
assign wb_sel_i = next_wb_sel_i ? 4'b1111 : 4'b0000;

assign sHRDATA = wb_dat_o;
assign sHRESP = {1'b0, is_HRESP};
assign sHREADYOUT = wb_stb_i ? wb_ack_o : 1'b1;

always@(*) begin
    next_HRESP = 1'b0;
    
    next_wb_cyc_i = 1'b0;
    next_wb_stb_i = 1'b0;
    next_wb_sel_i = 1'b0;

    next_wb_we_i = 1'b0;
    next_wb_adr_i = 8'h00;
    if(sHSEL) begin
        if(sHREADY) begin
            next_wb_cyc_i = 1'b1;
            next_wb_stb_i = 1'b1;
            next_wb_sel_i = 1'b1;

            next_wb_adr_i = ito_wb_adr_i;
            next_wb_we_i = ito_wb_we_i;

            if(sHSIZE != 3'b010) begin // size != 32bit)
                if(sHTRANS == AHB_TRANS_IDLE) begin // No data
                    next_HRESP = 1'b0;
                end
                else begin
                    next_HRESP = 1'b1;
                end
            end
            else begin
                case (sHTRANS)
                    AHB_TRANS_IDLE: begin
                    end
                    AHB_TRANS_BUSY: begin
                    end
                    AHB_TRANS_NONSEQ, AHB_TRANS_SEQ: begin
                        next_wb_adr_i = sHADDR;
                        next_wb_we_i = sHWRITE;
                    end
                endcase
            end
        end
    end
end

always@(posedge clk or negedge reset_n) begin
    if(!reset_n) begin
        is_HRESP <= 1'b0;

        ito_wb_we_i <= 1'b0;
        ito_wb_adr_i <= 8'h00;
    end
    else begin
        is_HRESP <= next_HRESP;

        ito_wb_adr_i <= next_wb_adr_i;
        ito_wb_we_i <= next_wb_we_i;
    end
end

//////////// SDCard Controller
WishboneSpiMasterCtrl spi_master_ctrl(
                          .io_wishbone_CYC(wb_cyc_i),
                          .io_wishbone_STB(wb_stb_i),
                          .io_wishbone_ACK(wb_ack_o),
                          .io_wishbone_WE(wb_we_i),
                          .io_wishbone_ADR(wb_adr_i),
                          .io_wishbone_DAT_MISO(wb_dat_o),
                          .io_wishbone_DAT_MOSI(wb_dat_i),
                          .io_spi_ss(spi_ss),
                          .io_spi_sclk(spi_sclk),
                          .io_spi_mosi(spi_mosi),
                          .io_spi_miso(spi_miso),
                          //   .io_interrupt,
                          .clk(clk),
                          .reset(~reset_n)
                      );

endmodule
